package com.example.stock.controller;

import com.example.stock.controller.dto.MonthPctStatDTO;
import com.example.stock.controller.vo.LevelPointDecreaseVO;
import com.example.stock.controller.vo.MonthPctStatVO;
import com.example.stock.controller.vo.StockInfoVO;
import com.example.stock.model.MonthDetail;
import com.example.stock.model.MonthSat;
import com.example.stock.service.IndustryDataService;
import com.example.stock.service.MonthDataService;
import com.example.stock.service.StockService;
import com.example.stock.util.*;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;


@Log4j2
@Slf4j
@CrossOrigin(origins = "*")
@RequestMapping("month")
@RestController
public class MonthDataController {

    @Autowired
    MonthDataService monthDataService;

    @Autowired
    StockService stockService;

    @Autowired
    IndustryDataService industryDataService;

    @GetMapping("{stock}")
    Result index(@PathVariable("stock") String stock) {
        return ResultGenerator.genSuccessResult(monthDataService.getMonthData(stock));
    }

    @GetMapping("multiStock")
    Result multiStock(@RequestParam("stocks") String stocks) {
        String[] split = stocks.split(DataUtil.STOCK_SPLIT);
        return ResultGenerator.genSuccessResult(monthDataService.getMonthRawData(List.of(split)));
    }

    //获取指定行业数据
    @GetMapping("industry/{industry}")
    public Result industry(@PathVariable("industry") String industry) {
        return ResultGenerator.genSuccessResult(monthDataService.getMonthRawData(industryDataService.getStocksByTag(industry)));
    }

    private final int LIMIT = 72;

    @GetMapping("lpDecrease")
    Result lpDecreaseMonth(@RequestParam(required = false) String month) {

        LevelPointDecreaseVO levelPointDecreaseVO = new LevelPointDecreaseVO();

        // 倒序
        List<String> dates = monthDataService.getLpDecreaseKeys(LIMIT);
        levelPointDecreaseVO.setDates(dates);

        if (month == null) {
            levelPointDecreaseVO.setData(monthDataService.getLevelPointDecreaseByDate(dates.getFirst()));
        } else {
            levelPointDecreaseVO.setData(monthDataService.getLevelPointDecreaseByDate(month));
        }

        return ResultGenerator.genSuccessResult(levelPointDecreaseVO);
    }

    @GetMapping("monthPctStat")
    public Result getMonthPctStatByMonth(@RequestParam(required = false) String month) {

        MonthPctStatVO monthPctStatVO = new MonthPctStatVO();

        List<String> months = monthDataService.getMonthPctStatKeys();
        monthPctStatVO.setMonths(months);

        List<MonthDetail> monthPctStatList;
        if (month != null) {
            monthPctStatList = monthDataService.getMonthRawDataByDate(month);
        } else {
            monthPctStatList = monthDataService.getMonthRawDataByDate(months.getFirst());
        }

        monthPctStatVO.setData(formatData(monthPctStatList));
        return ResultGenerator.genSuccessResult(monthPctStatVO);
    }

    private List<MonthPctStatDTO> formatData(List<MonthDetail> monthPctStatList) {

        List<MonthPctStatDTO> ret = new ArrayList<>();
        monthPctStatList.forEach(i -> {

            MonthPctStatDTO monthPctStatDTO = new MonthPctStatDTO();
            BeanUtils.copyProperties(i, monthPctStatDTO);
            monthPctStatDTO.setGt60m(i.getGt1200d());

            StockInfoVO stockInfo = stockService.getStockInfo(i.getStock());
            // stockInfo
            monthPctStatDTO.setRank(stockInfo.getRank());
            monthPctStatDTO.setCategory(stockInfo.getCategory());
            monthPctStatDTO.setIndustry(stockInfo.getIndustry());

            ret.add(monthPctStatDTO);
        });

        return ret;
    }

    @GetMapping("stat")
    @Cacheable(value = "month_stat")
    public Result stat() {

        // 中证全指数据
        Map<String, MonthDetail> index = monthDataService.getMonthRawData("中证全指")
                .stream().collect(Collectors.toMap(MonthDetail::getDate, i -> i));

        List<MonthSat> monthSats = monthDataService.getMonthSat();

        Map<String, Map<String, Object>> ret = new TreeMap<>();
        monthSats.forEach(monthSat -> {

            Map<String, Object> item = new HashMap<>();

            int total = monthSat.getAmount();
            int increaseCount = monthSat.getPctGet0();
            int lpLt10Count = monthSat.getLpLet10();

            String date = monthSat.getDate();

            item.put("date", date);
            item.put("中证全指", index.get(date).getMonthPct());
            item.put("中证全指LP", index.get(date).getLp());
            item.put("总记录数", total);
            item.put("上涨个数", increaseCount);
            item.put("上涨比率", NumberUtil.floor((double)increaseCount / (double)total * 100, 2));
            item.put("LP小于10个数", lpLt10Count);
            item.put("LP小于10比率", NumberUtil.floor((double) lpLt10Count / (double) total * 100, 2));
            item.put("新增LP小于10个数", monthDataService.getLevelPointDecreaseByDate(date).stream().filter(p -> p.getLpDuration() == 1).count());
            item.put("连续下跌3个月", monthSat.getDe3m());
            item.put("连续下跌4个月", monthSat.getDe4m());
            item.put("连续下跌3个月及以上", monthSat.getDeGet3m());

            ret.put(date, item);
        });

        return ResultGenerator.genSuccessResult(ret.values());
    }
}
